<template>
	<view class="luch-audio__warp">
		<view class="luch-audio__cover" :class="{ 'luch-audio--cover-bg': !poster }">
			<image :src="poster" v-if="poster" class="luch-audio__cover-img"></image>
			<view class="luch-audio__play-btn" :class="{ 'luch-audio--btn-pause': videoIsPlay }" @click="handleBtnClick"></view>
		</view>
		<view class="luch-audio__audio-con">
			<view class="luch-audio__audio-info">
				<text class="luch-audio__audio-title luch-audio--text-eill">{{ name }}</text>
				<!-- <text class="luch-audio__audio-author luch-audio--text-eill">{{ author }}</text> -->
			</view>
			<view class="luch-audio__audio-time">{{ audioTimeUpdate }}</view>
		</view>
	</view>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, defineProps, defineEmits } from 'vue';

/**
 * 将秒转换为 分:秒
 * @param {Number} s - 秒数
 */
function sToHs(s) {
	let h = Math.floor(s / 60);
	s = s % 60;
	h = h.length === 1 ? '0' + h : h;
	s = s.length === 1 ? '0' + s : s;
	return h + ':' + s;
}

const props = defineProps({
	play: {
		type: Boolean,
		default: false
	},
	src: {
		type: String
	},
	poster: {
		type: String,
		default: ''
	},
	name: {
		type: String,
		default: '未知音频'
	},
	author: {
		type: String,
		default: '未知作者'
	},
	autoplay: {
		type: Boolean
	},
	loop: {
		type: Boolean
	},
	obeyMuteSwitch: {
		type: Boolean
	},
	initAudio: {
		type: Function
	},
	index: {
		type: [String, Number]
	}
});

const emit = defineEmits(['update:play', 'onPlay', 'onPause', 'onEnded', 'onTimeUpdate', 'onError']);

const audioTimeUpdate = ref('00:00');
const videoIsPlay = ref(false);
let innerAudioContext = null;

watch(() => props.play, (n) => {
	if (n) {
		!videoIsPlay.value && audioPlay();
	} else {
		videoIsPlay.value && audioPause();
	}
});

watch(() => props.src, () => {
	audioDestroy();
	contextInit();
});

onMounted(() => {
	contextInit();
});

onBeforeUnmount(() => {
	audioDestroy();
});

function audioPlay() {
	innerAudioContext && innerAudioContext.play();
}

function audioPause() {
	innerAudioContext && innerAudioContext.pause();
}

function audioOnPlay() {
	videoIsPlay.value = true;
	emit('update:play', true);
}

function audioOnPause() {
	videoIsPlay.value = false;
	emit('update:play', false);
}

function audioDestroy() {
	innerAudioContext && innerAudioContext.destroy && innerAudioContext.destroy();
	audioPropInit();
}

function audioControls() {
	if (videoIsPlay.value) {
		audioPause();
	} else {
		audioPlay();
	}
}

function handleBtnClick() {
	audioControls();
	emit('update:play', videoIsPlay.value);
}

function contextInit() {
	emit('update:play', false);
	if (!props.src) {
		if (process.env.NODE_ENV !== 'production') {
			console.warn(`[luch-audio warn]: 'src' 为空`);
		}
		return;
	}
	innerAudioContext = uni.createInnerAudioContext();
	innerAudioContext.autoplay = props.autoplay;
	innerAudioContext.loop = props.loop;

	innerAudioContext.onPlay((...arg) => {
		audioTimeUpdate.value = sToHs(Math.floor(innerAudioContext.currentTime));
		audioOnPlay();
		emit('onPlay', ...arg);
	});
	innerAudioContext.onPause((...arg) => {
		audioOnPause();
		emit('onPause', ...arg);
	});
	innerAudioContext.onEnded((...arg) => {
		audioOnPause();
		emit('onEnded', ...arg);
	});
	innerAudioContext.onTimeUpdate((...arg) => {
		audioTimeUpdate.value = sToHs(Math.floor(innerAudioContext.currentTime));
		emit('onTimeUpdate', ...arg);
	});
	innerAudioContext.onError((...arg) => {
		emit('onError', ...arg);
	});
	innerAudioContext.src = props.src;
	if (props.initAudio) {
		props.initAudio(innerAudioContext, { src: props.src, index: props.index });
	}
}

function audioPropInit() {
	audioTimeUpdate.value = '00:00';
	videoIsPlay.value = false;
}
</script>

<style lang="scss" scoped>
.luch-audio--text-eill {
	/*超出省略号*/
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.luch-audio__warp {
	display: flex;
	overflow: hidden;
	height: 67px;
	border-radius: 3px;
	border: 1px solid #e0e0e0;
}
.luch-audio__cover {
	position: relative;
	flex-shrink: 0;
	width: 65px;
	height: 100%;
	&.luch-audio--cover-bg {
		background-color: #e6e6e6;
	}
	.luch-audio__cover-img {
		width: 100%;
		height: 100%;
	}
	.luch-audio__play-btn {
		position: absolute;
		left: 50%;
		top: 50%;
		width: 24px;
		height: 24px;
		transform: translateX(-50%) translateY(-50%);
		border-radius: 50%;
		background-size: 100% 100%;
		background-image: url('');
		&.luch-audio--btn-pause {
			background-image: url('');
		}
	}
}
.luch-audio__audio-con {
	position: relative;
	flex: 1;
	display: flex;
	width: 0;
	padding: 0 15px;
	align-items: center;
	background-color: #fcfcfc;
	.luch-audio__audio-info {
		width: 100%;
	}
	.luch-audio__audio-title {
		display: block;
		padding-bottom: 7px;
		padding-right: 25px;
		font-size: 14px;
		color: #353535;
	}
	.luch-audio__audio-author {
		display: block;
		font-size: 12px;
		color: #888888;
	}
	.luch-audio__audio-time {
		position: absolute;
		right: 15px;
		top: 6px;
		font-size: 13px;
		color: #9d9d9d;
	}
}
</style>
